package muhnes.sizoo.consulta;

import java.io.Serializable;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;

public class Filtro implements Serializable, IConsultable, Comparable<Filtro> {
    
    static {
        Map<TipoComparacion,String> temp = new EnumMap<TipoComparacion,String>(TipoComparacion.class);
        temp.put(TipoComparacion.IGUAL, "%s = %s");
        temp.put(TipoComparacion.DISTINTO, "%s != %s");
        temp.put(TipoComparacion.MENOR, "%s < %s");
        temp.put(TipoComparacion.MENOR_IGUAL, "%s <= %s");
        temp.put(TipoComparacion.MAYOR, "%s > %s");
        temp.put(TipoComparacion.MAYOR_IGUAL, "%s >= %s");
        temp.put(TipoComparacion.CONTIENE, "%s IN (%s)");
        temp.put(TipoComparacion.NO_CONTIENE, "%s NOT IN (%s)");
        temp.put(TipoComparacion.INCLUYE, "%s LIKE %s");
        mapeoComparaciones = Collections.unmodifiableMap(temp);
    }
    
    private final static Map<TipoComparacion,String> mapeoComparaciones; 
    
    static {
        Map<TipoComparacion,String> temp = new EnumMap<TipoComparacion,String>(TipoComparacion.class);
        temp.put(TipoComparacion.IGUAL, "Igual a");
        temp.put(TipoComparacion.DISTINTO, "Distinto de");
        temp.put(TipoComparacion.MENOR, "Menor que");
        temp.put(TipoComparacion.MENOR_IGUAL, "Menor o igual que");
        temp.put(TipoComparacion.MAYOR, "Mayor que");
        temp.put(TipoComparacion.MAYOR_IGUAL, "Mayor o igual que");
        temp.put(TipoComparacion.CONTIENE, "Contenido en");
        temp.put(TipoComparacion.NO_CONTIENE, "No contenido en");
        temp.put(TipoComparacion.INCLUYE, "Incluye");
        etiquetaComparaciones = Collections.unmodifiableMap(temp);
    }
    
    public final static Map<TipoComparacion,String> etiquetaComparaciones; 
    
    private Campo campo;
    private TipoComparacion comparacion;
    private String valor;
    private boolean requerido;
    
    public Filtro() {
    }

    public Filtro(Campo campo, TipoComparacion comparacion, String valor, boolean requerido) {
        this.campo = campo;
        this.comparacion = comparacion;
        this.valor = valor;
        this.requerido = requerido;
    }

    public Campo getCampo() {
        return campo;
    }

    public void setCampo(Campo campo) {
        this.campo = campo;
    }

    public TipoComparacion getComparacion() {
        return comparacion;
    }

    public void setComparacion(TipoComparacion comparacion) {
        this.comparacion = comparacion;
    }

    public String getValor() {
        return valor;
    }

    public void setValor(String valor) {
        this.valor = valor;
    }
    
    public boolean isRequerido() {
        return requerido;
    }

    public void setRequerido(boolean requerido) {
        this.requerido = requerido;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Filtro other = (Filtro) obj;
        if (this.campo != other.campo && (this.campo == null || !this.campo.equals(other.campo))) {
            return false;
        }
        if (this.comparacion != other.comparacion) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 71 * hash + (this.campo != null ? this.campo.hashCode() : 0);
        hash = 71 * hash + (this.comparacion != null ? this.comparacion.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Filtro{" + "campo=" + campo + ", comparacion=" + comparacion + ", valor=" + valor + ", requerido=" + requerido +'}';
    }

    @Override
    public String getValorConsultable() {
        String patronComparacion = mapeoComparaciones.get(comparacion);
        String consultable = String.format(
            patronComparacion, 
            campo.getFuente().getValor() + "." + campo.getValor(),
            campo.formatearValor(valor)
        );
        return consultable;
    }

    @Override
    public int compareTo(Filtro filtro) {
        return campo.getNombre().compareTo(filtro.getCampo().getNombre());
    }
    
}
